comment |
  This program shows how to remap any or all keys on the keyboard.
  The position in the long list below represents the key codes sent
  to the keyboard intercept (Int 15H, service 4FH) from Int 9H.  Change
  the codes for any keys you want to remap.  Be sure you change both
  the make and break codes for each key.  If you want a key to be
  ignored completely, change its code to 00H.
  Save as: KBREMAP.ASM
  Compile: MASM KBREMAP;
  	   LINK KBREMAP;		(ignore no-stack warning)
	   EXE2BIN KBREMAP.EXE KBREMAP.COM
	|

cseg	segment
	assume cs:cseg, ds:nothing
		org	100h			;.COM file format
start:		jmp	install

old15		equ	this dword
old15_off	dw	?
old15_seg	dw	?

keytbl:	db	000h,001h,002h,003h,004h,005h,006h,007h
	db	008h,009h,00Ah,00Bh,00Ch,00Dh,00Eh,00Fh
	db	010h,011h,012h,013h,014h,015h,016h,017h
	db	018h,019h,01Ah,01Bh,01Ch,038h,01Eh,01Fh ;L. Ctrl = ALT
	db	020h,021h,022h,023h,024h,025h,026h,027h
	db	028h,029h,02Ah,02Bh,02Ch,02Dh,02Eh,02Fh
	db	030h,031h,032h,033h,034h,035h,036h,037h
	db	03Ah,039h,01Dh,03Bh,03Ch,03Dh,03Eh,03Fh	;L. Alt = Caps Lock
	db	040h,041h,042h,043h,044h,045h,046h,047h	;& CAPS LOCK = Ctrl
	db	048h,049h,04Ah,04Bh,04Ch,04Dh,04Eh,04Fh
	db	050h,051h,052h,053h,054h,055h,056h,057h
	db	058h,059h,05Ah,05Bh,05Ch,05Dh,05Eh,05Fh
	db	060h,061h,062h,063h,064h,065h,066h,067h
	db	068h,069h,06Ah,06Bh,06Ch,06Dh,06Eh,06Fh
	db	070h,071h,072h,073h,074h,075h,076h,077h
	db	078h,079h,07Ah,07Bh,07Ch,07Dh,07Eh,07Fh
	db	080h,081h,082h,083h,084h,085h,086h,087h
	db	088h,089h,08Ah,08Bh,08Ch,08Dh,08Eh,08Fh
	db	090h,091h,092h,093h,094h,095h,096h,097h
	db	098h,099h,09Ah,09Bh,09Ch,0B8h,09Eh,09Fh ;L. Ctrl = ALT
	db	0A0h,0A1h,0A2h,0A3h,0A4h,0A5h,0A6h,0A7h
	db	0A8h,0A9h,0AAh,0ABh,0ACh,0ADh,0AEh,0AFh
	db	0B0h,0B1h,0B2h,0B3h,0B4h,0B5h,0B6h,0B7h
	db	0BAh,0B9h,09Dh,0BBh,0BCh,0BDh,0BEh,0BFh ;L. Alt = Caps Lock
	db	0C0h,0C1h,0C2h,0C3h,0C4h,0C5h,0C6h,0C7h	;& CAPS LOCK = Ctrl
	db	0C8h,0C9h,0CAh,0CBh,0CCh,0CDh,0CEh,0CFh
	db	0D0h,0D1h,0D2h,0D3h,0D4h,0D5h,0D6h,0D7h
	db	0D8h,0D9h,0DAh,0DBh,0DCh,0DDh,0DEh,0DFh
	db	0E0h,0E1h,0E2h,0E3h,0E4h,0E5h,0E6h,0E7h
	db	0E8h,0E9h,0EAh,0EBh,0ECh,0EDh,0EEh,0EFh
	db	0F0h,0F1h,0F2h,0F3h,0F4h,0F5h,0F6h,0F7h
	db	0F8h,0F9h,0FAh,0FBh,0FCh,0FDh,0FEh,0FFh

new15:		pushf				;Save flags
		cmp	ah,4fh			;KB Intercept?
		je	key_xlate		;Yes -- translate
exit:		popf				;Recover flags
		jmp	cs:[old15]		;Go to previous Int 15H

key_xlate:	push	di			;Save register
		sub	ah,ah			;AX = original value
		mov	di,offset keytbl	;DI ==> table
		add	di,ax			;DI ==> entry
		mov	al,cs:[di]		;Get new value
		mov	ah,4fh			;Restore AH
		pop	di			;Recover registers
		or	al,al			;Is new key 0?
		jnz	exit			;No -- exit through old 15H
		popf				;Else pop flags
		clc				;Clear carry flag
		retf	2			;Simulate IRET to Int 9H
end_tsr		equ	$

signon		db	'Keyboard translation now in effect.$'

		assume cs:cseg, ds:cseg
install:	mov	ax,3515h		;Get Int 15H vector
		int	21h			;  from DOS
		mov	[old15_off],bx		;Save for later
		mov	[old15_seg],es
		mov	dx,offset new15		;Set new Int 15H
		mov	ax,2515h		;  vector through
		int	21h			;  DOS
		mov	dx,offset signon	;Report we're here
		mov	ah,9
		int	21h
		mov	dx,offset end_tsr	;Point to end of resident
		int	27h			;code and exit
cseg		ends
		end	start

